<?php
class cmsdream_helper {
	public $db;
	public $config;
	public $setting;
	
	//protected $_ID = 0;
	//protected $_offset = 0;
	
	public function format_content($pee, $br = 1) {
		if ( trim($pee) === '' )
			return '';
		$pee = $pee . "\n"; // just to make things a little easier, pad the end
		// save the pre tags
		$_pre = array();
		if(preg_match_all('/(<pre[^>]*>)(.*?)<\/pre>/is', $pee, $matches)) {
			foreach($matches[1] as $key => $row) {
				$_pre[] = $row . htmlspecialchars($matches[2][$key]) . '</pre>';
			}
			foreach($matches[0] as $key => $row) {
				$pee = str_replace($row, "<pre>[$key]</pre>", $pee);
			}
		}
		
		$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
		// Space things out a little
		$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|option|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)';
		$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
		$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
		$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
		if ( strpos($pee, '<object') !== false ) {
			$pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
			$pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
		}
		$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
		// make paragraphs, including one at the end
		$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
		$pee = '';
		foreach ( $pees as $tinkle )
			$pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
		$pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
		$pee = preg_replace('!<p>([^<]+)</(div|address|form)>!', "<p>$1</p></$2>", $pee);
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
		$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
		$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
		$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
		if ($br) {
			$pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function(
							'$matches',
							'
								return str_replace("\n", "<CMSDreamNewline />", $matches[0]);
							'
						), $pee);
			$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
			$pee = str_replace('<CMSDreamNewline />', "\n", $pee);
		}
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
		$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
		
		if (strpos($pee, '<pre') !== false) {
			$pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', create_function(
							'$matches',
							'
								if ( is_array($matches) )
									$text = $matches[1] . $matches[2] . "</pre>";
								else
									$text = $matches;

								$text = str_replace("<br />", "", $text);
								$text = str_replace("<p>", "\n", $text);
								$text = str_replace("</p>", "", $text);

								return $text;
							'
						), $pee );
		}
		// restore the pre tags.
		if(preg_match_all('/<pre>\[([\d]+)\]<\/pre>/i', $pee, $matches)) {
			foreach($matches[0] as $key => $row) {
				$_rep = isset($_pre[$key]) ? $_pre[$key] : '';
				$pee = str_replace($row, $_rep, $pee);
			}
		}
		
		$pee = preg_replace( "|\n</p>$|", '</p>', $pee );

		return $pee;
	}
	
	public function get_post_thumbnail($pid, $tid){
		$gallery = $this->get_post_gallery_by_id($pid);
		if(empty($gallery)) return '';
		if(isset($gallery[$tid])) {
			$img = $this->construct_attachment_image($gallery[$tid], 'post-thumbnail', false);
			if(preg_match('/<img[^\>]+src="([^"]+)"[^\>]+>/i', $img, $matches))
			return $matches[1];
			else
			return '';
		}
		return '';
	}
	
	public function replace_gallery($pid, $str, $galleryLimit = 0) {
		if(!preg_match_all('/\[gallery([^\]]*)\]/is', $str, $matches)) return $str;
		$str = preg_replace('/<p>(\[gallery([^\]]*)\])<\/p>/is', '$1', $str);

		$gs = array();
		foreach($matches[1] as $key => $match) {
			$gs[$key] = new stdClass();
			if(preg_match('/order="(desc|asc)"/is', $match, $a)){
				$gs[$key]->order = strtolower($a[1]);
			} else {
				$gs[$key]->order = "desc";
			}
			if(preg_match('/columns="([1-9]{1})"/is', $match, $a)){
				$gs[$key]->columns = $a[1];
			} else {
				$gs[$key]->columns = "3";
			}
			if(preg_match('/orderby="(menu_order|id|rand|title)"/is', $match, $a)){
				$gs[$key]->orderby = strtolower($a[1]);
			} else {
				$gs[$key]->orderby = "menu_order";
			}
		}
		
		foreach($matches[0] AS $key => $match){
			$str = str_replace($match, $this->construct_gallery($pid, $gs[$key], $galleryLimit), $str);
		}
		
		return $str;
	}
	
	public function get_post_previous_and_next($pid, $t = 'next', $parent = 0, $type = 'post', $status = 'publish', $order = 'post_date') {
		$tb = $this->config->TABLE_PREFIX;
		$c = ($t == 'next') ? array('<', 'DESC') : array('>', 'ASC');
		
		$fields = array("ID","post_date AS `date`","post_title AS title");
		$fields = implode(',',$fields);
		$imgct = ($type=='attachment') ? " AND post_mime_type LIKE 'image/%'" : "";
		$where = " post_type = '$type' AND post_status = '$status' AND post_parent = $parent $imgct ";
		$pdate = "(SELECT $order FROM {$tb}posts WHERE ID = $pid LIMIT 1)";
		$data = $this->db->fetch("SELECT $fields FROM {$tb}posts WHERE $order ".$c[0]." $pdate AND $where ORDER BY $order ".$c[1]." LIMIT 1");
		if(!empty($data)){
			$data->title = htmlspecialchars($data->title);
			$data->url = $GLOBALS['E']->url('post', $data->ID);
		}
		return $data;
	}
	
	private function get_post_gallery_by_id($pid){
		$tb = $this->config->TABLE_PREFIX;
		$cache = $GLOBALS['E'];
		$gallery = $cache->get("gallery-by-post-id-$pid");
		if(!$gallery) {
			$gallery = array();
			$ids = array(0);
			foreach($this->db->fetch_all("SELECT ID AS id,post_date AS `date`,post_title AS title,menu_order,post_mime_type 
							FROM {$tb}posts WHERE post_status = 'inherit' AND post_type = 'attachment' AND post_parent = $pid
							ORDER BY menu_order DESC") AS $key => $row){
				if(preg_match('/^image\//is', $row->post_mime_type)){
					$gallery[$row->id] = new stdClass();
					$gallery[$row->id]->id = $row->id;
		            $gallery[$row->id]->date = $row->date;
		            $gallery[$row->id]->title = htmlspecialchars($row->title);
		            $gallery[$row->id]->menu_order = $row->menu_order;
		            $ids[] = $row->id;
				}
			}
			
			foreach($this->db->fetch_all("SELECT post_id,meta_key,meta_value FROM {$tb}postmeta WHERE post_id IN(".implode(',',$ids).")") AS $key => $row){
				if(preg_match('/^([a-z])\:([\d]+)\:\{(.*)\}$/i', $row->meta_value) || preg_match('/^([a-z])\:([\d]+)\:"stdClass"\:([\d]+)\:\{(.*)\}$/i', $row->meta_value)) {
					$gallery[$row->post_id]->{$row->meta_key} = unserialize($row->meta_value);
				} else {
					$gallery[$row->post_id]->{$row->meta_key} = $row->meta_value;
				}
			}
			if(!empty($gallery)) $cache->write("gallery-by-post-id-$pid", str_replace("'", "\\'", serialize($gallery)), (time() + $GLOBALS['C']->CACHETIME));
		}
		unset($cache, $tb);
		return $gallery;
	}
	
	private function construct_gallery($pid, $g, $galleryLimit = 0) {
		$gallery = $this->get_post_gallery_by_id($pid);
		if(empty($gallery)) return '';
		$galleryLimit = $galleryLimit<=0 ? count($gallery) : intval($galleryLimit);

		//需要排序  $g
		//menu_order|id|rand|title
		$s = array();
		//if($g->orderby=='menu_order' && $g->order=='desc') {
			foreach($gallery as $gg){
				$s[] = $gg;
			}
		//}
		
		$max = $galleryLimit % $g->columns == 0 ? $galleryLimit : $galleryLimit + ($g->columns - $galleryLimit % $g->columns);
		
		$str  = '';
		$str .= '<table width="100%" cellpadding="3" cellspacing="3" border="0" class="gallery" id="gallery-'.$pid.'">';
		$str .= '<tr>';
		for($i = 1; $i <= $max; $i++){
			$str .= '<td width="'.intval(100/$g->columns).'%" valign="top">';
			if($i <= $galleryLimit && isset($s[$i-1])) {
				$str .= $this->construct_attachment_image($s[$i-1]);
			} else {
				$str .= '&nbsp;';
			}
			$str .= '</td>';
			if( $i % $g->columns == 0 && $i < $max)
			$str .= '</tr><tr>';
			
		}
		$str .= '</tr>';
		$str .= "</table>\n";
		return $str;
	}
	
	private function construct_attachment_image($arr, $key = 'thumbnail', $link = true){
		if(!isset($arr->_wp_attachment_metadata) || empty($arr->_wp_attachment_metadata)) return '&nbsp;';
		$pathinfo = pathinfo($arr->_wp_attachment_metadata['file']);
		$path = $this->setting->upload_url_path . '/' . $pathinfo['dirname'] . '/';
		if(isset($arr->_wp_attachment_metadata['sizes'])){
			$sizes = $arr->_wp_attachment_metadata['sizes'];			
			if(isset($sizes[$key]))
			$img = $sizes[$key]['file'];
			else
			$img = $pathinfo['basename'];
		}else{
			$img = $pathinfo['basename'];
		}
		
		$img = '<img src="'.$path . $img.'" title="'.$arr->title.'" />';
		if($link){
			$cache = $GLOBALS['E'];
			$url = $cache->url('attachment', $arr->id);
			unset($cache);
			return '<a href="'.$url.'" id="attachment-'.$arr->id.'">'.$img.'</a>';
		}else{
			return $img;
		}
	}
	
	public function __construct(){
		
	}
	
	public function __destruct(){
		
	}
}